﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// Reviewed

#pragma once
#include "GcmpMathInterface.h"

#include "GbmpDefines.h"
#include "MathUtils.h"
#include "Vector2d.h"
#include "Vector3d.h"
#include "Coordinate3d.h"

namespace gcmp
{
    /// \brief Vector2d的工具类
    ///
    /// 
    class GCMP_MATH_INTERFACE_EXPORT Vector2dUtils
    {
    public:

        /// \brief  计算两个点的距离
        ///
        /// \param point1  点
        /// \param point2 另一个点
        /// \return   距离
        static double Distance(const Vector2d& point1, const Vector2d& point2);

        /// \brief   计算两个点的距离平方
        ///
        /// \param point1  点
        /// \param point2  另一个点
        /// \return   距离平方
        static double SqrDistance(const Vector2d& point1, const Vector2d& point2);

        /// \brief   判断点或向量是否在给定误差下相等
        ///
        /// \param vec1  向量
        /// \param vec2  另一向量
        /// \param typeTol 误差
        /// \return  true: 相等   false: 不等
        static bool IsEqual(const Vector2d& vec1, const Vector2d& vec2, double typeTol = gcmp::Constants::DOUBLE_EPS);

        /// \brief   判断两个向量是否平行
        ///
        /// \param vec1  向量
        /// \param vec2  另一向量
        /// \param typeTol  容差
        /// \return   true: 平行   false: 不平行
        static bool IsParallel(const Vector2d& vec1, const Vector2d& vec2, const double& typeTol = gcmp::Constants::DOUBLE_EPS);

        /// \brief   判断两个向量是否垂直
        ///
        /// \param vec1  向量
        /// \param vec2  另一向量
        /// \param typeTol  容差
        /// \return   true: 垂直   false: 不垂直
        static  bool IsPerpendicular(const Vector2d& vec1, const Vector2d& vec2, double typeTol = gcmp::Constants::DOUBLE_EPS);

         /// \brief  将输入向量旋转给定角度
         ///
        /// \param vec  输入向量
        /// \param radian  旋转角度的弧度值，正值表示逆时针方向
        /// \return  旋转后的向量
        static Vector2d Rotate(const Vector2d& vec, double radian);

        /// \brief   将点绕着指定中心点旋转给定角度
        ///
        /// \param point  平面上一点
        /// \param center  中心点
        /// \param radian  旋转角度的弧度值，正值表示逆时针方向
        /// \return   旋转后的点
        static Vector2d RotateAroundPt(const Vector2d& point, const Vector2d& center, double radian);

        /// \brief   计算给定向量逆时针转到该向量的转角,要求两个向量为单位向量
        ///
        /// \param vecUnitFrom  起始向量
        /// \param vecUnitTo  终止向量
        /// \return  弧度值         [0; 2PI]
        static double GetAngle(const Vector2d& vecUnitFrom, const Vector2d& vecUnitTo);

    public:

        /// \brief   获取两个向量的夹角(锐角)，向量不考虑方向
        ///
        /// \param vec1  向量
        /// \param vec2  另一向量
        /// \return   [0, PI/2]
        static double GetAcuteAngle(const Vector2d& vec1, const Vector2d& vec2);

        /// \brief   判断一个向量是否在两个向量之间(包含在向量上的情形)
        ///
        /// \param vec  某个向量
        /// \param vec1  其中一个边界向量
        /// \param vec2  另一个边界向量
        /// \param tol  容差
        /// \return  true 在两向量vec1,vec2之间，false, 不在两向量vec1,vec2之间
        static bool IsBetweenTwoVectors(const Vector2d& vec, const Vector2d& vec1, const Vector2d& vec2, double tol = Constants::DOUBLE_EPS);
    };
}


